package com.bg.print.config.securityconfig;

import com.alibaba.fastjson2.JSON;
import com.bg.print.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * @program: bg-print-java
 * @description: 权限管理
 * @author: liuxvru
 * @create: 2024-03-23 17:41
 **/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity()
@Slf4j
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //authorizeHttpRequests()：开启授权保护
        //anyRequest()：对所有请求开启授权保护
        //authenticated()：已认证请求会自动被授权
        http.authorizeHttpRequests(authorizeRequests ->
                        authorizeRequests
                                .requestMatchers("/user/buyer/save").permitAll()
                                .requestMatchers("/user/merchant/save").permitAll()
                                .requestMatchers("/v3/**").permitAll()
                                .requestMatchers("/doc.html").permitAll()
                                .requestMatchers("/webjars/**").permitAll()
                                .requestMatchers("/material/materials").permitAll()
                                .requestMatchers("/alipay/notify/**").permitAll()
                                .requestMatchers("/file/**").permitAll()
                                .anyRequest().authenticated() // 其他所有请求都需要认证
                )
                .formLogin(withDefaults())//表单授权方式
                .httpBasic(withDefaults());//基本授权方式

        http.formLogin(form -> {
            form.loginPage("/user/login").permitAll()
                    .successHandler(new MyAuthenticationSuccessHandler())//成功返回
                    .failureHandler(new MyAuthenticationFailureHandler());//失败返回
        });

        http.logout(logout -> {
            logout.logoutUrl("/user/logout").permitAll()
                    .logoutSuccessHandler(new MyLogoutSuccessHandler()); //注销成功时的处理
        });

        //错误处理
        http.exceptionHandling(exception -> {
            exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());//请求未认证的接口
            exception.accessDeniedHandler((request, response, e) -> { //请求未授权的接口
                log.error(e.getLocalizedMessage());
                //转换成json字符串
                String json = JSON.toJSONString(R.error(403, "没有权限"));
                //返回响应
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().println(json);
            });
        });

        //会话管理
        http.sessionManagement(session -> {
            session
                    .maximumSessions(1)
                    .expiredSessionStrategy(new MySessionInformationExpiredStrategy());
        });

        //关闭csrf
        http.csrf()
                .disable()
                .sessionManagement()
                .maximumSessions(1);
        return http.build();
    }
}